// 1、编写一个类装饰器 `@Log`，在类实例化时打印日志（如 `new User()` 时输出 `User instance created`）
// 类装饰器 - 在类实例化时打印日志
function Log<T extends { new (...args: any[]): {} }>(target: T) {
  // 返回一个新的构造函数
  return class extends target {
    constructor(...args: any[]) {
      console.log(`${(target as any).name} instance created`);
      super(...args);
    }
  };
}

@Log
class User {
  id: number;
  
  constructor(id: number) {
    this.id = id;
  }
  
  getInfo() {
    console.log(`User ID: ${this.id}`);
  }
}

// 测试装饰器功能
console.log('=== 测试类装饰器 ===');
const user1 = new User(1);
const user2 = new User(2);

user1.getInfo();
user2.getInfo();

// 2、编写一个方法装饰器 `@Validate`，校验方法的参数是否为字符串（非字符串则抛出错误）
function Validate(target: any, propertyName: string, descriptor: PropertyDescriptor) {
  console.log(target, propertyName, descriptor)
  const method = descriptor.value;
  
  descriptor.value = function(...args: any[]) {
    args.forEach((arg, index) => {
      if (typeof arg !== 'string') {
        throw new Error(`参数 ${index + 1} 必须是字符串类型，但收到了 ${typeof arg}`);
      }
    });
    return method.apply(this, args);
  };
  
  return descriptor;
}

class Greeter {
  @Validate
  greet(greeting: string | number) {
    console.log(`Greeting: ${greeting}`);
  }
}

console.log('\n=== 测试方法装饰器 ===');
const greeter = new Greeter();

// 测试正常情况
try {
  greeter.greet("Hello World");
} catch (error: any) {
  console.error('错误:', error.message);
}

// 测试错误情况
try {
  greeter.greet(123);
} catch (error: any) {
  console.error('错误:', error.message);
}

export {}